package com.iscas.lndicatormonitor.controller;

import com.iscas.lndicatormonitor.common.CustomResult;
import com.iscas.lndicatormonitor.domain.HistoryPwd;
import com.iscas.lndicatormonitor.domain.Loginattempt;
import com.iscas.lndicatormonitor.domain.Role;
import com.iscas.lndicatormonitor.domain.Users;
import com.iscas.lndicatormonitor.dto.LoginRes;
import com.iscas.lndicatormonitor.dto.UsersDTO;
import com.iscas.lndicatormonitor.service.*;
import com.iscas.lndicatormonitor.utils.JwtTokenUtil;
import com.iscas.lndicatormonitor.utils.LoginAttemptUtil;
import com.iscas.lndicatormonitor.utils.MD5Utils;
import org.apache.catalina.User;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@RequestMapping("/user")
@RestController
public class UsersController {
    @Autowired
    UsersService usersService;

    @Autowired
    RoleService roleService;

    @Autowired
    HistoryPwdService historyPwdService;

    @Autowired
    LoginAttemptUtil loginAttemptUtil;
    @Autowired
    LoginattemptService loginattemptService;

    @Autowired
    TokenBlacklistService tokenBlacklistService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @PostMapping("/login")
    public CustomResult userLogin(@RequestBody UsersDTO usersDTO) throws Exception {
        JwtTokenUtil jwtTokenUtil = new JwtTokenUtil();
        try{
            Users loginResult = usersService.userLogin(usersDTO);
            if (loginResult != null && loginResult.getId() > 0) {
                // 检查 Redis 中当前用户的活跃会话数
                Long currentSessions = redisTemplate.opsForList().size("active_sessions:" + loginResult.getId());
                System.out.println(currentSessions);
                if (currentSessions >= 5) { // 假设最大会话数为 5
                    return new CustomResult(40000, "达到最大会话数", null);
                }

                // 生成 Token
                String token = jwtTokenUtil.generateToken(usersDTO.getUsername());

                // 将 Token 添加到 Redis
                redisTemplate.opsForList().leftPush("active_sessions:" + loginResult.getId(), token);
                redisTemplate.expire("active_sessions:" + loginResult.getId(), 1, TimeUnit.HOURS); // 设置过期时间为1小时
                BeanUtils.copyProperties(loginResult,usersDTO);
                Role role =  roleService.selectByUserId(loginResult.getId());
                usersDTO.setReal_name(loginResult.getRealName());
                usersDTO.setPassword("xxxxxx");
                usersDTO.setRole(role.getRoleType());
                LoginRes loginRes = new LoginRes();
                loginRes.setUsersDTO(usersDTO);
                loginRes.setToken(token);
                return new CustomResult(20000,"登录成功",loginRes);
            } else {
                Users user =  usersService.selectByUserName(usersDTO.getUsername());
                // 处理登录失败的情况
                if (loginResult != null && loginAttemptUtil.isLocked(user.getId())){
                    // 处于被锁定的状态
                   Loginattempt loginattempt =  loginattemptService.selectByUserId(user.getId());
                    // 获取当前时间
                    Date now = new Date();
                    // 获取 LockUntil 时间
                    Date lockUntil = loginattempt.getLockUntil();
                    // 计算时间差异（以毫秒为单位）
                    long diffInMillies = Math.abs(lockUntil.getTime() - now.getTime());
                    return new CustomResult(40000,"账户已被锁定，请于"+TimeUnit.MINUTES.convert(diffInMillies, TimeUnit.MILLISECONDS)+"分钟后再试",5);
                }else {
                    if (loginResult == null){
                        // 用户名不正确
                        return new CustomResult(40000,"用户名不存在",null);
                    }else {
                        // 密码不正确
                        loginAttemptUtil.handleLoginError(user.getId());
                        Loginattempt loginattempt =  loginattemptService.selectByUserId(user.getId());
                        return new CustomResult(40000,"密码错误",loginattempt.getLoginAttempts());
                    }
                }
            }
        }catch (Exception e){
            return new CustomResult(40000,e.toString(),null);
        }
    }

    @GetMapping("/logout")
    public CustomResult logout(String token) throws Exception {
//        if (token != null && token.startsWith("Bearer ")) {
//            token = token.substring(7);
//        }
        JwtTokenUtil jwtTokenUtil = new JwtTokenUtil();
        String username = jwtTokenUtil.getUsernameFromToken(token);
        Users user = usersService.selectByUserName(username);
        System.out.println(user);
        if (user != null) {
            // 从 Redis 中移除 Token
            redisTemplate.opsForList().remove("active_sessions:" + user.getId(), 0, token);
        }
        try{
            tokenBlacklistService.blacklistToken(token);
            return new CustomResult(20000,"注销成功！",null);
        }catch (Exception e){
            return new CustomResult(40000,"注销失败！",null);
        }
    }
    @PostMapping("/addUser")
    public CustomResult addUser(@RequestBody UsersDTO usersDTO){
        MD5Utils md5Utils = new MD5Utils();
        usersDTO.setPassword(md5Utils.encrypted("123456"));
        // 先检查是否有相同的用户名
        if (usersService.isHaveCommonUser(usersDTO.getUsername())) {
            return  new CustomResult(40000,"用户名重复",null);
        }
        try{
            int userId = usersService.usersInsert(usersDTO);
            System.out.println(userId);
            if (userId >0){
                // 处理角色信息
                Role role = new Role();
                role.setUserid(userId);
                role.setRoleType(usersDTO.getRole());
                roleService.insert(role);
                return new CustomResult(20000,"新增成功！",null);
            }else {
                return new CustomResult(40000,"新增失败",null);
            }
        }catch (Exception e){
            return new CustomResult(40000,e.toString(),null);
        }
    }

    @GetMapping("/getAllUser")
    public CustomResult getAllUser() throws Exception {
        try {
            List<UsersDTO> usersDTOS = usersService.getAllUsersDto();
            return new CustomResult(20000,"获取成功",usersDTOS);
        }catch (Exception e){
            return new CustomResult(40000,"获取失败",null);
        }
    }
    @GetMapping("/deleteUser")
    public CustomResult deleteUser(@RequestParam(value = "userId", required = false) Integer userId) throws Exception {
        // 检查 userId 是否为 null
        if (userId == null) {
            return new CustomResult(40000, "用户ID未提供", null);
        }

        System.out.println(userId);
        int result = usersService.deleteById(userId);
        if (result == 1) {
            return new CustomResult(20000, "删除成功！", null);
        } else {
            return new CustomResult(40000, "删除失败！", null);
        }
    }

    @PostMapping("/alterUser")
    public CustomResult alterUser(@RequestBody UsersDTO usersDTO) throws Exception {
        int result =  usersService.updateUser(usersDTO);
        if (result == 1){
            return new CustomResult(20000,"更新成功！",null);
        }else {
            return new CustomResult(40000,"更新失败！",null);
        }
    }

    // 判断是否是第一次登录
    @GetMapping("/isFirstLogin")
    public CustomResult isFirstLogin(int userId){
       List<HistoryPwd> historyPwdList = historyPwdService.selectLastFiveByUserId(userId);
       if (historyPwdList.size() == 0){
           return new CustomResult(20000,"第一次登录",null);
       }else {
           return new CustomResult(30000,"第n次登录",null);
       }
    }

    // 判断当前密码是否超过180d
    @GetMapping("/isPwdPastDue")
    public CustomResult isPwdPastDue(int userId){
        HistoryPwd lastHistoryPwd = historyPwdService.selectLastFiveByUserId(userId).get(0);
        boolean isExpired = isPasswordExpired(lastHistoryPwd);
        if (isExpired){
            return new CustomResult(20000,"已过期",null);
        }else {
            return new CustomResult(40000,"未过期",null);
        }
    }

    // 修改密码
    @PostMapping("/updatePwd")
    public  CustomResult updatePwd(@RequestBody UsersDTO usersDTO) throws Exception {
        System.out.println(usersDTO);
        Integer result = usersService.updatePwd(usersDTO);
        if (result == 1){
            return new CustomResult(20000,"修改成功",null);
        } else if (result == 2) {
            return new CustomResult(40000,"不能与当前密码重复",null);
        } else if (result == 3) {
            return new CustomResult(40000,"不能与最近历史修改记录重复",null);
        }
        return new CustomResult(40000,"修改失败",null);
    }
    public boolean isPasswordExpired(HistoryPwd lastHistoryPwd) {
        // 将 Date 类型的 changedate 转换为 LocalDate
        LocalDate changeDate = lastHistoryPwd.getChangedate().toInstant()
                .atZone(ZoneId.systemDefault()).toLocalDate();

        // 获取当前日期
        LocalDate currentDate = LocalDate.now();

        // 计算两个日期之间的天数差异
        long daysBetween = java.time.temporal.ChronoUnit.DAYS.between(changeDate, currentDate);

        // 检查是否超过了180天
        return daysBetween > 180;
    }

}